package com.pai4j.connect.filter;

import com.pai4j.connect.service.RedisHealthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Redis熔断器过滤器
 * 当Redis不可用时，提供降级处理
 *
 * @author: CYM-pai
 * @date: 2025/08/27 23:47
 **/
@Slf4j
@Component
@Order(1)
public class RedisCircuitBreakerFilter implements Filter {

    @Autowired
    private RedisHealthService redisHealthService;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        // 检查Redis健康状态
        if (!redisHealthService.isRedisAvailable()) {
            log.warn("Redis is not available, applying circuit breaker for request: {}", httpRequest.getRequestURI());
            
            // 对于WebSocket连接请求，添加特殊处理
            if (isWebSocketRequest(httpRequest)) {
                // 设置响应头，告知客户端Redis服务不可用
                httpResponse.setHeader("X-Redis-Status", "UNAVAILABLE");
                httpResponse.setHeader("X-Fallback-Mode", "ENABLED");
            }
        }
        
        // 继续执行请求链
        chain.doFilter(request, response);
    }

    /**
     * 判断是否为WebSocket请求
     *
     * @param request HTTP请求
     * @return true表示是WebSocket请求
     */
    private boolean isWebSocketRequest(HttpServletRequest request) {
        String upgrade = request.getHeader("Upgrade");
        return "websocket".equalsIgnoreCase(upgrade);
    }
}
